Types of Development#
In this notebook, for the “at risk” sites, we will classify what is causing them to be the most at risk, from housing, offices, and industrial.
Show code cell source
#First recreate the data from the preliminary analysis
import geopandas as gpd
import pandas as pd
# Load and join GMCA housing, industrial and office supply data
housing_supply_gdf = gpd.read_file("data/gmca_data/2024 GM Housing Land Supply GIS.shp")
industrial_supply_gdf = gpd.read_file("data/gmca_data/2024 GM Industrial-warehousing Land Supply GIS.shp")
offices_supply_gdf = gpd.read_file("data/gmca_data/2024 GM Offices Land Supply GIS.shp")
total_supply_gdf = pd.concat(
[housing_supply_gdf, industrial_supply_gdf, offices_supply_gdf]
)
# Load and tidy GMEU Sites of Biological Importance data
sbi_gdf = gpd.read_file("data/gmeu_data/gm_sbi.shp")
sbi_gdf["Category"] = "Site of Biological Importance"
sbi_gdf = sbi_gdf.rename(columns = {"district": "LAName", "site_nam": "SiteRef"})
# Join GMCA and GMEU data
full_data_gdf = pd.concat(
[total_supply_gdf, sbi_gdf[["SiteRef", "LAName", "Category", "geometry"]]]
)
#Use geopandas to get centroids of all the sites
full_data_gdf["centroid"] = full_data_gdf.centroid
full_data_gdf["ref"] = range(len(full_data_gdf))
#Split into sites of biological importance and non-biological importance
sbi = full_data_gdf[full_data_gdf["Category"] == "Site of Biological Importance"]
non_sbi = full_data_gdf[full_data_gdf["Category"] != "Site of Biological Importance"]
#Find the number of new developments less than 1km away for each SBI
sbinames = list(sbi["SiteRef"]) #list of all the sbis
indexes = list(sbi["ref"])
distances = list()
less_than_1km = list() #creating empty lists to add to data frame
for x in sbi["centroid"]: #loop through each sbi
y = non_sbi["centroid"].distance(x) #find all the distances of developments to centroid
for distance in y: #filter for less than 1km away
if distance <1000:
distances.append(distance)
r = len(distances) #find no. developments less than 1km away to each sbi
less_than_1km.append(r)
distances = list()
Dev_1km = pd.DataFrame({'SiteRef':sbinames, 'No. Sites in 1km': less_than_1km, 'ref': indexes}) #create dataframe of sbi and no. developments
Dev_1km
| SiteRef | No. Sites in 1km | ref | |
|---|---|---|---|
| 0 | Big Wood | 0 | 4357 |
| 1 | Winstanley Hall Woods | 1 | 4358 |
| 2 | Ackhurst Lane Sand Workings | 3 | 4359 |
| 3 | Abbey Lakes | 6 | 4360 |
| 4 | Wetland by M6 | 1 | 4361 |
| ... | ... | ... | ... |
| 531 | Mill Race & Pasture at Haughton Dale | 8 | 4888 |
| 532 | Three Sisters | 2 | 4889 |
| 533 | Nan Nook Wood | 7 | 4890 |
| 534 | Big Wood | 10 | 4891 |
| 535 | Bank Wood & Marsh | 11 | 4892 |
536 rows × 3 columns
Of the sites at risk, what type of development is posing the most risk?#
First remember what we found from the mapping sites at risk notebook, which was 45 SBI sites with 15 or more proposed developments within a 1km radius.
Dev_1km = Dev_1km[Dev_1km["No. Sites in 1km"] >= 15]
len(Dev_1km)
45
On a map this looks like:
Dev_1km = pd.merge(sbi, Dev_1km, on="ref")
Dev_1km.explore( tiles="CartoDB positron")
To find which sites are posing the most risk, repeat the steps to find how many sites are within 1km, but this time using separated datasets for each type of development.
#Filter data for each type of development from the full data which includes the centroid column.
Housing = full_data_gdf[full_data_gdf["Category"] == 'Housing']
Industrial = full_data_gdf[full_data_gdf["Category"] == 'Industrial/warehousing']
Offices = full_data_gdf[full_data_gdf["Category"] == 'Offices']
print(len(Housing) + len(Industrial) + len(Offices))
print(len(non_sbi))
4357
4357
sum(Dev_1km["No. Sites in 1km"])
929
Also, it is useful to note that there are 929 total developments that threaten our “at risk” locations. We can keep this in mind as a baseline for our further calculations.
Housing Risk#
#Find the number of new housing developments less than 1km away for each SBI
sbinames = list(Dev_1km["SiteRef_x"]) #list of all the sbis
indexes = list(Dev_1km["ref"])
distances = list()
less_than_1km = list() #creating empty lists to add to data frame
for x in Dev_1km["centroid"]: #loop through each sbi
y = Housing["centroid"].distance(x) #find all the distances of developments to centroid
for distance in y: #filter for less than 1km away
if distance <1000:
distances.append(distance)
r = len(distances) #find no. developments less than 1km away to each sbi
less_than_1km.append(r)
distances = list()
Housing_1km = pd.DataFrame({'SiteRef_x':sbinames, 'No. Sites in 1km': less_than_1km, 'ref': indexes}) #create dataframe of sbi and no. developments
print("There are " + str(sum(Housing_1km["No. Sites in 1km"])) + " new housing developments affecting the at risk sites.")
There are 807 new housing developments affecting the at risk sites.
Industrial Risk#
#Find the number of new industrial developments less than 1km away for each SBI
sbinames = list(Dev_1km["SiteRef_x"]) #list of all the sbis
indexes = list(Dev_1km["ref"])
distances = list()
less_than_1km = list() #creating empty lists to add to data frame
for x in Dev_1km["centroid"]: #loop through each sbi
y = Industrial["centroid"].distance(x) #find all the distances of developments to centroid
for distance in y: #filter for less than 1km away
if distance <1000:
distances.append(distance)
r = len(distances) #find no. developments less than 1km away to each sbi
less_than_1km.append(r)
distances = list()
Industrial_1km = pd.DataFrame({'SiteRef_x':sbinames, 'No. Sites in 1km': less_than_1km, 'ref': indexes}) #create dataframe of sbi and no. developments
print("There are " + str(sum(Industrial_1km["No. Sites in 1km"])) + " new industrial/warehouse developments affecting the at risk sites.")
There are 71 new industrial/warehouse developments affecting the at risk sites.
Offices Risk#
#Find the number of new office developments less than 1km away for each SBI
sbinames = list(Dev_1km["SiteRef_x"]) #list of all the sbis
indexes = list(Dev_1km["ref"])
distances = list()
less_than_1km = list() #creating empty lists to add to data frame
for x in Dev_1km["centroid"]: #loop through each sbi
y = Offices["centroid"].distance(x) #find all the distances of developments to centroid
for distance in y: #filter for less than 1km away
if distance <1000:
distances.append(distance)
r = len(distances) #find no. developments less than 1km away to each sbi
less_than_1km.append(r)
distances = list()
Offices_1km = pd.DataFrame({'SiteRef_x':sbinames, 'No. Sites in 1km': less_than_1km, 'ref': indexes}) #create dataframe of sbi and no. developments
print("There are " + str(sum(Offices_1km["No. Sites in 1km"])) + " new office developments affecting the at risk sites.")
There are 51 new office developments affecting the at risk sites.
Conclusion#
Above, we have found that there are 807 housing developments, 71 industrial developments and 51 office developments that are affecting our “at risk” sites.
Relevant to the way we calculate the “at risk” which is the number of sites within 1km of the sites of biological importance, this makes sense, as housing developments are generally much smaller, and much more frequent (consider the original map). Therefore there is a higher chance for them to be near an SBI site, and many housing developments can fit within 1km.
It also makes sense that Industrial developments cause slightly more risk than office developments, as they often are found on the outskirts of the city, and are therefore more likely to be closer to sites of biological importance.
full_data_gdf.explore("Category", cmap="tab10", tiles="CartoDB positron")